#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import os
import json
import uuid
import stat
import socket

from common.const import SysData, ParamConstant
from common.common import execute_cmd, output_execution_result_ex

from ndmp.comm.log import log
from ndmp.comm.const import NDMPCode, Constant


def get_env_in_variable(str_env_variable: str):
    env_variable = ''
    input_dict = json.loads(SysData.SYS_STDIN)
    if str_env_variable in input_dict.keys():
        env_variable = input_dict.get(str_env_variable)
    return env_variable


def is_dst_reachable(target_ip, source_ip, port):
    #多平面网络检测连通性
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置源IP地址
        sock.bind((source_ip, 0))
        sock.settimeout(Constant.TIMOUT)
        sock.connect((target_ip, port))
        sock.close()
        return True
    except Exception as e:
        log.error(e, exc_info=True)
        sock.close()
        return False


def report_job_details(req_id, job_id, job_detail: dict, interface_name="ReportJobDetails"):
    """
    功能描述：上报进度
    参数：无
    @job_id: 任务id
    @job_detail: 任务详情
    返回值：无
    """
    random_id = f'ndmp_{req_id}_' + str(uuid.uuid4())
    input_file = os.path.join(ParamConstant.PARAM_FILE_PATH, random_id + "_input")
    output_file = os.path.join(ParamConstant.RESULT_PATH, random_id + "_output")
    # 将任务状态写入文件
    output_execution_result_ex(input_file, job_detail)
    cmd = f"sh {ParamConstant.BIN_PATH}/rpctool.sh {interface_name} {input_file} {output_file}"
    code, out, err = execute_cmd(cmd)
    log.info(f'{interface_name}, code: {code}, out: {out}, err: {err}')
    flags = os.O_RDONLY
    modes = stat.S_IRUSR
    with os.fdopen(os.open(output_file, flags, modes), 'r', encoding=Constant.UTF_8) as file_read:
        result = json.load(file_read)
    remove_file(input_file)
    remove_file(output_file)
    ret = result.get("code", -1)
    if ret != NDMPCode.SUCCESS.value:
        log.error(f"{interface_name} failed, job id: {job_id}, ret: {ret}")
        return False
    else:
        log.info(f"{interface_name} success, job id: {job_id}")
        return True


def remove_file(file_path):
    if os.path.exists(file_path):
        os.remove(file_path)
    else:
        log.info(f"{file_path} is not exist, needn't remove")


def format_capacity(size):
    kb_size = 1024
    mb_size = 1024 * kb_size
    gb_size = 1024 * mb_size
    tb_size = 1024 * gb_size
    pb_size = 1024 * tb_size

    if kb_size < size < mb_size:
        size /= kb_size
        return str('%.2f' % size) + "KB"
    elif mb_size < size < gb_size:
        size /= mb_size
        return str('%.2f' % size) + "MB"
    elif gb_size < size < tb_size:
        size /= gb_size
        return str('%.2f' % size) + "GB"
    elif tb_size < size < pb_size:
        size /= tb_size
        return str('%.2f' % size) + "TB"
    elif size > pb_size:
        size /= pb_size
        return str('%.2f' % size) + "PB"
    else:
        return str(size) + "B"
